"use strict";

/* higher-order functions */

{
    function add(x, y, f) {
        return f(x) + f(y);
    }

    let x = -5;
    let y = 6;
    f = Math.abs;

    let r = add(-5, 6, f);
    console.log(r);
    // < 11
}

/* map and reduce */
{
    let pow = function (x) {
        return x * x;
    }

    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    let results = arr.map(pow);
    console.log(results);
    // [1, 4, 9, 16, 25, 36, 49, 64, 81]

    arr.map(String);
    // ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
}

{
    let arr = [1, 3, 5, 7, 9];
    arr.reduce(function (x, y) {
        return x + y;
    });
    // < 25

    arr.reduce(function (x, y) {
        return x * y;
    });
    // < 945

    arr.reduce(function (x, y) {
        return x * 10 + y;
    })
}

{
    let s = "13579";
    let arr = [];
    for (let c of s) {
        arr.push(c - '0');
    }

    let num = arr.reduce(function (x, y) {
        return x * 10 + y;
    });

    console.log(num);
    // 13579
}

{
    let ename = ["adam", "LISA", "barT"];

    function normalize(arr) {
        function normalize_one(s) {
            return s[0].toUpperCase() + s.substr(1).toLowerCase();
        }

        arr.map()
        return arr.map(normalize_one);
    }

    normalize(ename);
    // ["Adam", "Lisa", "Bart"]
}

{
    let arr = ['1', '2', '3'];
    let r;
    r = arr.map(parseInt);

    console.log(r);
    // 1, NaN, NaN
}


/* filter */
{
    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 10, 15];
    let r = arr.filter(function (x) {
        return x % 2 !== 0;
    });

    r;
    // [1, 3, 5, 7, 15]
}

{
    let arr = ['A', '', 'B', null, undefined, 'C', ' '];
    let r = arr.filter(function (s) {
        return s && s.trim();
        // trim: Removes the leading and trailing white space 
        //       and line terminator characters from a string.
    });

    r;
    // ["A", "B", "C"]
}

{
    let arr = ['A', 'B', 'C'];
    let r = arr.filter(function (value, index, array) {
        console.log(value);
        console.log(index);
        console.log(array);

        return true;
    });
    // A
    // 0
    // (3)["A", "B", "C"]
    // B
    // 1
    // (3)["A", "B", "C"]
    // C
    // 2
    // (3)["A", "B", "C"]
}

{
    let
        r,
        arr = ["apple", "banana", "pear", "apple", "orange", "banana"];

    r = arr.filter(function (value, index, array) {
        return array.indexOf(value) === index;
    });

    console.log(r);
}

{
    let isPrime = function (num) {
        let ret = true;

        if (num <= 1) {
            ret = false;
        }
        else {
            for (let i = 2; i <= Math.floor(Math.sqrt(num)); i++) {
                if (num % i === 0) {
                    ret = false;
                    break;
                }
            }
        }

        return ret;
    }

    let get_primes = function (arr) {
        r = arr.filter(isPrime);

        return r;
    }


    // check
    let arr = [];
    for (let x = 1; x < 100; x++) {
        arr.push(x);
    }
    r = get_primes(arr);
    console.log(r);
    // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 
    //  43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
}


/* sort */
{
    let arr = [2, 10, 20, 1, 2];

    arr.sort(function (a, b) {
        let ret = 0;
        if (a < b) { 
            ret = -1;
            // console.log("a, b");
            // console.log(a, b);
        }
        else if (a > b) {
            ret = 1;
            // console.log("b, a");
            // console.log(b, a);
        }
        // console.log(arr);
        
        return ret;
    });
    // < [1, 2, 2, 10, 20]

    arr.sort(function (a, b) {
        return a < b ? 1 : -1;
    });
    // < [20, 10, 2, 2, 1]
}

{
    let arr = ["abc", "abcd", "AbcD", "aCd", "acbd"];
    arr.sort();
    // < ["AbcD", "aCd", "abc", "abcd", "acbd"]

    arr.sort(function (s1, s2) {
        x1 = s1.toUpperCase();
        x2 = s2.toUpperCase();
        return x1 < x2 ? -1 : 1;
    });
    // < ["abc", "AbcD", "abcd", "acbd", "aCd"]
}

/* Array */
{
    let arr = ["Apple", "pear", "orange"];
    console.log(arr.every(function (s) {
        return s.length > 0;
    }));
    // true

    console.log(arr.every(function (s) {
        return s.toLowerCase() === s;
    }));
    // false
}

{
    let arr = ["Apple", "pear", "orange"];
    console.log(arr.find(function (s) {
        return s.toLowerCase() === s;
    }));
    // pear

    console.log(arr.find(function (s) {
        return s.toUpperCase() === s;
    }));
    // undefined
}

{
    let arr = ["Apple", "pear", "orange"];
    console.log(arr.findIndex(function (s) {
        return s.toLowerCase() === s;
    }));
    // 1

    console.log(arr.findIndex(function (s) {
        return s.toUpperCase() === s;
    }));
    // -1
}

{
    let arr = ["Apple", "pear", "orange"];
    arr.forEach(console.log);
    // Apple  0 (3) ["Apple", "pear", "orange"]
    // pear   1 (3) ["Apple", "pear", "orange"]
    // orange 2 (3) ["Apple", "pear", "orange"]
}